#ifndef FAKE_TESTS_H
#define FAKE_TESTS_H

#include <cppunit/extensions/HelperMacros.h>

#include "Fake.h"

namespace FakeTests
{
    class ITestClass
    {
    public:
        virtual void voidMethodWithNoArguments() = 0;
        virtual void voidMethodWithOneArgument(int a) = 0;
        virtual void voidMethodWithTwoArguments(int a, int b) = 0;
        virtual void voidMethodWithThreeArguments(int a, int b, int c) = 0;
        virtual void voidMethodWithFourArguments(int a, int b, int c, int d) = 0;

        virtual int nonVoidMethodWithNoArguments() = 0;
        virtual int nonVoidMethodWithOneArgument(int a) = 0;
        virtual int nonVoidMethodWithTwoArguments(int a, int b) = 0;
        virtual int nonVoidMethodWithThreeArguments(int a, int b, int c) = 0;
        virtual int nonVoidMethodWithFourArguments(int a, int b, int c, int d) = 0;
    };

    class When_spawned : public CPPUNIT_NS::TestFixture
    {
        CPPUNIT_TEST_SUITE(FakeTests::When_spawned);
        CPPUNIT_TEST(Assure_calling_abstract_method_throws_exception);
        CPPUNIT_TEST_SUITE_END();

    public:
        void Assure_calling_abstract_method_throws_exception();

    private:
        Fake<ITestClass> _testClass;
    };

    class When_defining_behavior : public CPPUNIT_NS::TestFixture
    {
        CPPUNIT_TEST_SUITE(FakeTests::When_defining_behavior);

        CPPUNIT_TEST(Assure_allowing_void_method_with_no_arguments);
        CPPUNIT_TEST(Assure_allowing_void_method_with_one_arguments);
        CPPUNIT_TEST(Assure_allowing_void_method_with_two_arguments);
        CPPUNIT_TEST(Assure_allowing_void_method_with_three_arguments);
        CPPUNIT_TEST(Assure_allowing_void_method_with_four_arguments);

        CPPUNIT_TEST(Assure_allowing_non_void_method_with_no_arguments);
        CPPUNIT_TEST(Assure_allowing_non_void_method_with_one_arguments);
        CPPUNIT_TEST(Assure_allowing_non_void_method_with_two_arguments);
        CPPUNIT_TEST(Assure_allowing_non_void_method_with_three_arguments);
        CPPUNIT_TEST(Assure_allowing_non_void_method_with_four_arguments);

        CPPUNIT_TEST_SUITE_END();

    public:
        void Assure_allowing_void_method_with_no_arguments();
        void Assure_allowing_void_method_with_one_arguments();
        void Assure_allowing_void_method_with_two_arguments();
        void Assure_allowing_void_method_with_three_arguments();
        void Assure_allowing_void_method_with_four_arguments();

        void Assure_allowing_non_void_method_with_no_arguments();
        void Assure_allowing_non_void_method_with_one_arguments();
        void Assure_allowing_non_void_method_with_two_arguments();
        void Assure_allowing_non_void_method_with_three_arguments();
        void Assure_allowing_non_void_method_with_four_arguments();

    private:
        Fake<ITestClass> _testClass;
    };
}

#endif
